D) Constructor & Initialization

Default Constructor & Constructor with parameter
#include <iostream>
class Fraction{
private:
int m_numerator;
int m_denominator;
public:
Fraction() // default constructor
{
m_numerator=0;
m_denominator=1;
}
int getNumerator(){return m_numerator; }
int getDenominator(){return m_denominator; }
double getValue(){return static_cast<double>(m_numerator)/m_denominator;}
};
int main(void){
Fraction frac; // call class with default constructor
std::cout<<frac.getNumerator()<<'/'<<frac.getDenominaotr()<<'\n';
return
}
인자 없이 Fraction 타입의 인스턴스를 생성할 때, 객체에 메모리가 할당된 직후 default constructor가 호출됨
(만일 기본 생성자가 없었다면, 위 변수들의 값을 명시적으로 할당할 때까지, 쓰레기값을 가지고 있음)
기본 자료형인 멤버변수는 자동으로 초기화 되지 않음
#include <cassert>
class Fraction
{
private:
int m_numerator;
int m_denominator;
public:
Fraction() // default constructor
{
m_numerator=0;
m_denominator=1;
}
// constructor with two parameter(one parameter have default value)
Fraction(int numerator, int denominator=1)
{
assert(denominator!=0);
m_numerator=numerator;
m_denominator=denominator;
}
int getNumerator(){return m_numerator; }
int getDenominator(){return m_denominator; }
double getValue(){return static_cast<double>(m_numerator)/m_denominator; }
};
int main(void){
int x(5); // Direct initialize an integer
Fraction fiveThirds(5, 3); // Direct initializae of a Fraction
int x{5}; // Uniform initialization of an integer;
Fraction fiveThirds{5, 3}; //Uniform initialization of a Fraction
}
클래스와 대입 연산자(=)을 이용한 복사 초기화
Fraction six=Fraction(6); // Copy initialize a Fraction
// Fraction(6, 1);
Fraction seven=7; //Copy initialize a Fraction
// 7 Fraction .
// Fraction Fraction(7, 1) constructor
Initialization
int value1=1; // (copy initialization)
double value2(2.2); // (direct initialization)
char value3 {'c'}; // (uniform initialization)
할당 & 초기화
생성자 본문을 통해 할당(직접 초기화로 사용)
class exam_class
{
private:
int m_value1;
double m_value2;
char m_value3;
const int m_value;
public:
exam_class(){ // default constructor
//
// ,
m_value1=1;
m_value2=2.2;
m_value3='c';
// m_value=1; // error: const
}
};
멤버 초기화 리스트(직접 초기화로 사용)
생성자 매개 변수 뒤에 삽입된다. 콜론(‘ : ‘)으로 시작한 이후, 초기화 할 각 변수를 쉼표로 구분하여
해당 변수의 값과 함께 나열(세미콜론(‘ ; ‘)으로 끝나지 않음
class exam_class
{
private:
int m_value1;
double m_value2;
char m_value3;
public:
exam_class(): m_value(1), m_value2(2.2), m_value3('c')//
{
//
}
};
유니폼 초기화(유니폼 초기화로 사용)
C++11부터 지원
class exam_class
{
private:
const int m_value;
public:
exam_class(): m_value{5} //
{
//
}
};
초기화 리스트를 사용한 배열 멤버 초기화
class array
{
private:
const int m_array[5];
public:
array(): m_array {} // zero the member array( )
{
//
}
}
클래스인 멤버 변수 초기화
#include <iostream>
class A{
public:
A(int x){std::cout<<"A"<<x<<"\n"; }
};
class B{
private:
A m_a;
public:
B(int y): m_a(y-1) // A(int) constructor - m_a
{
std::cout<<"B"<<y<<'\n';
}
};
int main(void){
B b(5);
return 0;
}
b instance는 초기화 리스트를 먼저 실행(m_a 초기화, A(int) 호출)
이후, B의 생성자 본문이 실행됨
const나 reference 변수처럼 초기값이 필요한 멤버를 초기화하기 위해서는 멤버 초기화 리스트를 사용해야 함
Member initialization(멤버 초기화)
C++11 에서는 클래스의 일반 멤버 변수에 직접 초기값을 할당할 수 있다.
#include <iostream>
class Rectangle{
private:
double m_length=1.0; // default value
// double m_length{1.0};
double m_width=1.0;
// double m_width{1.0};
public:
void Print(){
std::cout<<"Length:"<<m_length<<", Width:"<<m_width<<std::endl;
}
};
int main(void){
Rectangle x;
x.Print();
}
위처럼 변수에 default value를 할당한 경우,
생성자에서 멤버 변수의 값을 지정하지 않는 경우, 멤버 초기화를 통해서 기본값을 할당함

기본값이 지정되어도, 생성자 멤버 초기화 리스트가 가장 우선됨
#include <iostream>
class Rectangle{
private:
double m_length=1.0;
double m_width=1.0;
public:
Rectangle(double length, double width): m_length(length), m_width(width)
{
// ( )
}
Rectangle(double length): m_length(length)
{
// m_length length
// m_width 1.0
}
void Print(){
std::cout<<"Length:"<<m_length<<", Width:"<<m_width<<std::endl;
}
};
int main(void){
Rectangle y{2.0, 3.0};
y.Print();
Rectnagle z{2.0};
z.Print();
return 0;
}
멤버 초기화는
= 연사자를 이용한 복사 초기화 방식
{} 를 이용한 유니폼 초기화 방식 을 지원하지만,

()을 이용한 직접 초기화 방식은 지원하지 않는다.